package de.baumann.browser.present

import android.util.Log
import com.fasterxml.jackson.core.JsonParseException
import de.baumann.browser.api.OdinObserver
import de.baumann.browser.api.net.vo.LoginInfo
import de.baumann.browser.base.BasePresenter
import de.baumann.browser.db.ETHWallet
import de.baumann.browser.iview.ImportWalletView
import de.baumann.browser.model.UserModel
import de.baumann.browser.utils.*
import de.baumann.browser.utils.web3j.ETHWalletUtils
import de.baumann.browser.utils.web3j.WalletDaoUtils
import io.reactivex.Observable
import io.reactivex.ObservableOnSubscribe
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit

class ImportWalletPresenter : BasePresenter<ImportWalletView>() {

    fun importWalleByKeystoret() {
        Observable.create(ObservableOnSubscribe<ETHWallet> { emitter ->
            try {
                val ethWallet = ETHWalletUtils.loadWalletByKeystore(view!!.getContent(), view!!.getPassword())
                if (ethWallet != null) {
                    val isSuccess = WalletDaoUtils.insertNewWallet(ethWallet);
                    if (isSuccess) {
                        emitter.onNext(ethWallet)
                    } else {
                        emitter.onError(Throwable("钱包导入失败"))
                    }
                }
            } catch (e: Exception) {
                emitter.onError(e)
            }
        }).throttleFirst(3, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<ETHWallet> {
                    override fun onComplete() {
                    }

                    override fun onSubscribe(d: Disposable) {
                    }

                    override fun onNext(t: ETHWallet) {
                        view!!.importSuccess(t)
                    }

                    override fun onError(e: Throwable) {
                        if ("Invalid password provided" == e.message) {
                            view!!.onError("密码错误");
                        } else if (e is JsonParseException) {
                            view!!.onError("KeyStore无效，请检查")
                        } else {
                            view!!.onError(e.message);
                        }
                    }
                });
    }

    fun importWalleByPrivateKey() {
        Observable.create(ObservableOnSubscribe<ETHWallet> { emitter ->
            try {
                val ethWallet = ETHWalletUtils.loadWalletByPrivateKey(view!!.getContent(), view!!.getPassword())
                if (ethWallet != null) {
                    val isSuccess = WalletDaoUtils.insertNewWallet(ethWallet)
                    if (isSuccess) {
                        emitter.onNext(ethWallet)
                    } else {
                        ETHWalletUtils.deleteFile(ethWallet.keystorePath)
                        emitter.onError(Throwable("钱包导入失败"))
                    }
                    emitter.onNext(ethWallet)
                }
            } catch (e: Exception) {
                emitter.onError(e)
            }
        }).throttleFirst(3, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<ETHWallet> {
                    override fun onComplete() {
                    }

                    override fun onSubscribe(d: Disposable) {
                    }

                    override fun onNext(t: ETHWallet) {
                        view!!.importSuccess(t)
                    }

                    override fun onError(e: Throwable) {
                        if ("Invalid password provided" == e.message) {
                            view!!.onError("密码错误");
                        } else {
                            view!!.onError(e.message);
                        }
                    }
                });
    }

    private val ETH_TYPE = "m/44'/60'/0'/0/0"
    fun importWalleByMnemonic() {
        Observable.create(ObservableOnSubscribe<ETHWallet> { emitter ->
            try {
                val arrMnemonic = view!!.getContent().split(" ")
                if (arrMnemonic == null || arrMnemonic.size < 12) {
                    emitter.onError(Throwable("助记词太短，请重新输入"))
                    return@ObservableOnSubscribe
                }

                val ethWallet = ETHWalletUtils.importMnemonic(ETH_TYPE, arrMnemonic, view!!.getPassword())
                if (ethWallet != null) {
                    val isSuccess = WalletDaoUtils.insertNewWallet(ethWallet)
                    if (isSuccess) {
                        emitter.onNext(ethWallet)
                    } else {
                        ETHWalletUtils.deleteFile(ethWallet.keystorePath)
                        emitter.onError(Throwable("钱包导入失败"))
                    }
                    emitter.onNext(ethWallet)
                }
            } catch (e: Exception) {
                emitter.onError(e)
            }
        }).throttleFirst(3, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<ETHWallet> {
                    override fun onComplete() {
                    }

                    override fun onSubscribe(d: Disposable) {
                    }

                    override fun onNext(t: ETHWallet) {
                        view!!.importSuccess(t)
                    }

                    override fun onError(e: Throwable) {
                        if ("Invalid password provided" == e.message) {
                            view!!.onError("密码错误");
                        } else {
                            view!!.onError(e.message);
                        }
                    }
                });
    }

    private val userModel: UserModel = UserModel()

    fun login() {
        userModel.login(view.setWalletAddress(), "")
                .subscribe(object : OdinObserver<LoginInfo>(view) {
                    override fun onSuccess(loginInfo: LoginInfo) {
                        saveUser(loginInfo)
                        UnicornUtil.setUserInfo(loginInfo)
                        saveInviteCode(loginInfo.inviteCode)
                        saveInviteCodeStatus(loginInfo.inviteId)
                        saveFormAddress(loginInfo.fromAddress)
                        Log.d("lwq", "onSuccess: ${"登录成功"}")
                    }
                })
    }

}